package com.java.service;

import com.java.bean.Express;
import com.java.dao.BaseExpressDao;
import com.java.dao.impl.ExpressDaoMysql;
import com.java.exception.DuplicateCodeException;
import com.java.util.RandomUtil;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class ExpressService {
    private static final BaseExpressDao expressDao = new ExpressDaoMysql();

    /**
     * 获取控制台所需的快递数据
     *
     * @return [{size:XXX,day:XXX},{size:XXX,day:XXX}]
     */
    public static List<Map<String, Integer>> console() {
        return expressDao.console();
    }

    /**
     * 获取快件分布图所需的快递数据
     *
     * @return [{name:XXX,value:XXX},{name:XXX,value:XXX}]
     */
    public static List<Map<String, Object>> map() {
        return expressDao.map();
    }

    /**
     * 查找快件
     *
     * @param limit    是否分页 true 是(默认）， false 查询所有
     * @param offset   起始索引
     * @param pageSize 获取的快递数量, 即使不分页，该参数也限制查询数量
     * @return 快递列表
     */
    public static List<Express> listExpress(boolean limit, int offset, int pageSize) {
        return expressDao.listExpress(limit, offset, pageSize);
    }

    /**
     * 根据 id 查询快递信息
     *
     * @param id 单号
     * @return 快递信息
     */
    public static Express getExpressById(int id) {
        return expressDao.getExpressById(id);
    }

    /**
     * 根据单号查询快递信息
     *
     * @param number 单号
     * @return 快递信息
     */
    public static Express getExpressByNumber(String number) {
        return expressDao.getExpressByNumber(number);
    }

    /**
     * 根据取件码查询快递信息
     *
     * @param code 取件码
     * @return 快递信息
     */
    public static Express getExpressByCode(String code) {
        return expressDao.getExpressByCode(code);
    }

    /**
     * 根据用户的手机号，查询快递信息
     *
     * @param userPhone 用户的手机号
     * @return 快递信息
     */
    public static List<Express> getExpressByUserphone(String userPhone) {
        return expressDao.getExpressByUserphone(userPhone);
    }

    /**
     * 根据用户的手机号，查询快递信息
     *
     * @param userPhone 用户的手机号
     * @param status    状态
     * @return 快递信息
     */
    public static List<Express> getExpressByUserphoneAndStatus(String userPhone, int status) {
        return expressDao.getExpressByUserphoneAndStatus(userPhone, status);
    }

    /**
     * 根据录入人的手机号，查询快递信息（快递员/柜子的历史记录）
     *
     * @param sysphone 录入人的手机号
     * @return 快递信息
     */
    public static List<Express> getExpressBySysphone(String sysphone) {
        return expressDao.getExpressByCphone(sysphone);
    }

    /**
     * 快件录入,  取件码自动生成
     *
     * @param express 快递单号 快递公司 收件人手机号码 收件人姓名 录入人手机号码
     * @return 生成的键
     */
    public static int insert(Express express, boolean sendMessage) {
        final String code = RandomUtil.generateCode();
        express.setCode(code);
        int key;
        try {
            final boolean b = (key = expressDao.insert(express)) > 0;
            if (b && sendMessage)
//              AlibabaSMSUtil.send(express.getUser().getUphone(), code);
                System.out.println("发送一条信息给手机 " + express.getUserphone() + ", 取件码为：" + code);
            return key;
        } catch (DuplicateCodeException e) {
            return insert(express, sendMessage);
        }
    }

    /**
     * 修改快递信息
     *
     * @param id         要修改的快递id
     * @param newExpress 新的快递单号 新的快递公司 新的收货人姓名 新的收件人手机号码 新的快递的状态 新的快递员手机号码
     * @return true 成功， false 失败
     */
    public static boolean update(int id, Express newExpress, boolean sendMessage) {
        if (newExpress.getUserphone() != null && newExpress.getEstatus() == 1) {
            return update(id, newExpress);
        }
        final String code = RandomUtil.generateCode();
        newExpress.setCode(code);
        if (newExpress.getUserphone() != null) {
            final Express express = getExpressById(id);
            if (delete(id)) {
                newExpress.setIntime(express.getIntime());
                return insert(newExpress, sendMessage) > 0;
            } else
                return false;
        }
        try {
            return expressDao.update(id, newExpress) > 0;
        } catch (DuplicateCodeException e) {
            return update(id, newExpress, sendMessage);
        }
    }

    // 解决状态码和手机号码同时更改的问题
    private static boolean update(int id, Express newExpress) {
        final Express express = getExpressById(id);
        if (delete(id)) {
            newExpress.setIntime(express.getIntime());
            int key = insert(newExpress, false);
            if (key > 0) {
                newExpress.setUserphone(null);
                return update(key, newExpress, false);
            }
        }
        return false;
    }

    /**
     * 根据id删除快递信息
     *
     * @param id 要删除的快递id
     * @return 影响行数
     */
    public static boolean delete(int id) {
        return expressDao.delete(id) > 0;
    }

    /**
     * 确认取件
     *
     * @param code 取件码
     * @return 影响行数
     */
    public static boolean updateState(String code) {
        return expressDao.updateState(code) > 0;
    }

    public static List<Object[]> getAllExpressRankByPhone() {
        return expressDao.getExpressRankByPhoneRangeOfIntime(null, null);
    }

    public static List<Object[]> getYearExpressRankByPhone() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return expressDao.getExpressRankByPhoneRangeOfIntime((year - 1) + "-01-01", year + "-01-01");
    }

    public static List<Object[]> getMonthExpressRankByPhone() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        return expressDao.getExpressRankByPhoneRangeOfIntime(year + "-" + (month - 1) + "-01", year + "-" + month + "-01");
    }

}
